package guda.house.biz.bo.impl;

import guda.house.biz.bo.ParkingFeeBO;
import guda.house.biz.query.EstateRuleQuery;
import guda.house.biz.query.ParkingQuery;
import guda.house.biz.query.ParkingRentRuleQuery;
import guda.house.biz.query.ParkingRuleQuery;
import guda.house.biz.util.PriceUtil;
import guda.house.dal.dao.BillParkingDAO;
import guda.house.dal.dao.ParkingDAO;
import guda.house.dal.dao.ParkingRentRuleDAO;
import guda.house.dal.dao.ParkingRuleDAO;
import guda.house.dal.dataobject.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by well on 15/11/16.
 */
public class ParkingFeeBOImpl implements ParkingFeeBO {

    private final static Logger logger = LoggerFactory.getLogger(ParkingFeeBOImpl.class);

    @Autowired
    private ParkingDAO parkingDAO;
    @Autowired
    private TransactionTemplate transactionTemplate;
    @Autowired
    private BillParkingDAO billParkingDAO;
    @Autowired
    private ParkingRuleDAO parkingRuleDAO;
    @Autowired
    private ParkingRentRuleDAO parkingRentRuleDAO;

    @Override
    public String stateFee(Long villageId) {
        ParkingQuery parkingQuery = new ParkingQuery();
        parkingQuery.setVillageId(villageId);
        final List<ParkingDO> parkingDOs = parkingDAO.selectForPage(parkingQuery);
        final List<String> unUseParking = new ArrayList<String>();
        final List<String> unRule = new ArrayList<String>();
        final List<String> unReady = new ArrayList<String>();
        final List<String> stated = new ArrayList<String>();
        final List<String> statSucess = new ArrayList<String>();
        final StringBuilder errorBuf = new StringBuilder();
        final StringBuilder statedBuf = new StringBuilder();
        final StringBuilder buf = new StringBuilder();

        ParkingRuleQuery parkingRuleQuery = new ParkingRuleQuery();
        parkingRuleQuery.setVillageId(villageId);
        List<ParkingRuleDO> parkingRuleDOs = parkingRuleDAO.selectForView(parkingRuleQuery);

        ParkingRentRuleQuery parkingRentRuleQuery = new ParkingRentRuleQuery();
        parkingRentRuleQuery.setVillageId(villageId);
        List<ParkingRentRuleDO> parkingRentRuleDOs = parkingRentRuleDAO.selectForView(parkingRentRuleQuery);

        final Map<Long, ParkingRuleDO> parkingRuleDOMap = new HashMap<Long, ParkingRuleDO>(20);
        for (ParkingRuleDO parkingRuleDO : parkingRuleDOs) {
            parkingRuleDOMap.put(parkingRuleDO.getVarId(), parkingRuleDO);
        }

        final Map<Long, ParkingRentRuleDO> parkingRentRuleDOMap = new HashMap<Long, ParkingRentRuleDO>(20);
        for (ParkingRentRuleDO parkingRentRuleDO : parkingRentRuleDOs) {
            parkingRentRuleDOMap.put(parkingRentRuleDO.getVarId(), parkingRentRuleDO);
        }
        //获取统计年度
        Calendar statCalendar = Calendar.getInstance();
        final int statYear = statCalendar.get(Calendar.YEAR) ;
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                for (ParkingDO parkingDO : parkingDOs) {
                      if(parkingDO.getBuyed() == null || parkingDO.getGmtStart() == null ){
                          unUseParking.add(parkingDO.getParkingName());
                          logger.warn("stat-parking-warn:" + "车位:" + parkingDO.getParkingName() + ",尚未使用，无法统计物业费");
                          errorBuf.append("车位:" + parkingDO.getParkingName() + ",尚未使用，无法统计物业费").append("\n");
                          continue;
                      }

                    List<Date> list = getStatMonth(parkingDO.getParkingId());
                    Calendar temp = Calendar.getInstance();
                    long fee = 0;
                    if(parkingDO.getBuyed().intValue() ==1 ) {
                        ParkingRuleDO parkingRuleDO = parkingRuleDOMap.get(parkingDO.getParkingTypeId());
                        if (parkingRuleDO == null) {
                            logger.warn("stat-parking-warn:" +  "车位:" + parkingDO.getParkingName()   + ",没有计费规则，无法统计车位费，建筑类型:" + parkingDO.getParkingType());
                            errorBuf.append("车位:" + parkingDO.getParkingName()   + ",没有计费规则，无法统计车位费，建筑类型:").append(parkingDO.getParkingType()).append("\n");
                            unRule.add(parkingDO.getParkingName());
                            continue;
                        }else{
                            fee = parkingRuleDO.getFeeUnit();
                        }
                    }else{
                        ParkingRentRuleDO parkingRentRuleDO = parkingRentRuleDOMap.get(parkingDO.getParkingTypeId());
                        if (parkingRentRuleDO == null) {
                            logger.warn("stat-parking-warn:" +  "车位:" + parkingDO.getParkingName()   + ",没有计费规则，无法统计车位费，建筑类型:" + parkingDO.getParkingType());
                            errorBuf.append("车位:" + parkingDO.getParkingName()   + ",没有计费规则，无法统计车位费，建筑类型:").append(parkingDO.getParkingType()).append("\n");
                            unRule.add(parkingDO.getParkingName());
                            continue;
                        }else{
                            fee = parkingRentRuleDO.getFeeUnit();
                        }
                    }
                    for(Date date:list){
                        temp.setTime(date);
                        int month = temp.get(Calendar.MONTH) + 1;
                        int year = temp.get(Calendar.YEAR);

                        BillParkingDO billParkingDO = new BillParkingDO();
                        billParkingDO.setSuiteId(parkingDO.getSuiteId());
                        billParkingDO.setIsPayed(0);
                        billParkingDO.setRecordYear(year);
                        billParkingDO.setRecordMonth(month);
                        billParkingDO.setParkingId(parkingDO.getParkingId());
                        long totalFee =   fee ;//单位为分
                        billParkingDO.setPayTotal(totalFee);
                        billParkingDO.setGmtEnd(temp.getTime());
                        Calendar calendarStart = Calendar.getInstance();
                        calendarStart.setTime(date);
                        calendarStart.add(Calendar.MONTH, -1);
                        billParkingDO.setGmtStart(calendarStart.getTime());
                        billParkingDAO.insert(billParkingDO);
                        statSucess.add(parkingDO.getParkingName());
                        logger.info("stat-parking-warn:" + "车位:" + parkingDO.getParkingName() + "，年度:" + year + ",月份:" + month+ ",车位费:" + PriceUtil.formatCNY(totalFee) + "元");
                        buf.append("车位:" + parkingDO.getParkingName() + "，年度:" + year + ",月份:" + month + ",车位费:" + PriceUtil.formatCNY(totalFee) + "元,已经生成").append("\n");


                    }



                }
            }
        });

        StringBuilder result = new StringBuilder();
        result.append("本小区共有").append(parkingDOs.size()).append("车位").append("\n")
                .append("共有").append(statSucess.size()).append("车位成功生成账单.").append("\n")
                .append("共有").append(unUseParking.size()).append("车位由于没有未使用，无法生成账单.").append("\n")
                .append("共有").append(unRule.size()).append("车位没有计费规则，无法生成账单").append("\n")
                .append("共有").append(unReady.size()).append("车位由于时间未到，无需生成账单").append("\n")
                .append("共有").append(stated.size()).append("车位已经生成过账单，无需生成账单").append("\n");
        result.append("详细信息:").append("\n");
        result.append(errorBuf).append("\n");
        result.append(statedBuf).append("\n");
        result.append(buf).append("\n");
        return result.toString();


    }

    //获取需要统计得月份
    private List<Date> getStatMonth(Long parkingId) {
        List<Date> list = new ArrayList<Date>();
        BillParkingDO billParkingDO = billParkingDAO.selectLatest(parkingId);
        ParkingDO parkingDO = parkingDAO.getParkingById(parkingId);
        Date gmtEnd = parkingDO.getGmtEnd();

        Date gmtDelivery = parkingDO.getGmtStart();
        Calendar deliveryCal = Calendar.getInstance();
        deliveryCal.setTime(gmtDelivery);

        Calendar statCalendar = Calendar.getInstance();
        if(gmtEnd.before(statCalendar.getTime())){
            statCalendar.setTime(gmtEnd);
        }else{
            int statYear = statCalendar.get(Calendar.YEAR);
            int statmonth = statCalendar.get(Calendar.MONTH);

            int deliveryMonth = deliveryCal.get(Calendar.MONTH);
            if (deliveryMonth <= statmonth) {
                statYear = +statYear + 1;
            }
            statCalendar.set(Calendar.YEAR, statYear);
            statCalendar.set(Calendar.MONTH, deliveryMonth - 1);
        }

        if (billParkingDO == null) {

            Date gmtDelivery2 = parkingDO.getGmtStart();
            Calendar deliveryCal2= Calendar.getInstance();
            deliveryCal2.setTime(gmtDelivery2);

            while (deliveryCal2.getTime().before(statCalendar.getTime())) {
                deliveryCal2.add(Calendar.MONTH, 1);
                list.add(deliveryCal2.getTime());
            }
        } else {

            Calendar deliveryCal2 = Calendar.getInstance();
            deliveryCal2.setTime(billParkingDO.getGmtStart());

            while (deliveryCal2.getTime().before(statCalendar.getTime())) {
                deliveryCal2.add(Calendar.MONTH, 1);
                list.add(deliveryCal2.getTime());
            }
        }
        return list;
    }

    public static void main(String[] args){

    }
}
